#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QPushButton>
#include "Solve24Game.h"
#include <string.h>
#include <QMessageBox>
#include <QIcon>
#include <QPalette>
#include <random>
#include "def.h"
#include <QTextStream>
#include <QDirIterator>
#include <QDebug>
#include <algorithm>
#include <ctype.h>
#include <stdlib.h>
#include <QWindow>
#include <QFile>
#include <Calculate.h>
#include <QLabel>
#include <QStatusBar>
#include "HelpMenu.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , ansMsg(this)
{
    uiInit();
    windowInit();
    lcdInit();
    buttonInit();
    textEditInit();
    menuInit();
    // statusBarInit();
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 把button放在右边并且对齐
// 输入：button的vector数组
// 输出：成功返回true，失败返回
bool MainWindow::moveButtonRight(std::vector<QPushButton *> bts) {
    int len = bts.size();
    if (len >= BUTTON_WIDTH_RATE) {
        qDebug() << "右对齐最多放" << BUTTON_WIDTH_RATE <<  "个按钮";
        return false;
    }
    int w = this->width(), h = this->height();
    int bw = w/BUTTON_WIDTH_RATE, bh = bw * 1.0 * BUTTON_RATE;
    for (auto &i: bts) {
        i->resize(bw, bh);
    }
    int mw = w - bw, mh = (h - bh * len) / 2;
    for (auto &i: bts) {
        i->move(mw, mh);
        mh += bh;
    }
    return true;
}

// 初始化窗口
void MainWindow::windowInit() {
    resize(WINDOW_SIZE_WIDTH, WINDOW_SIZE_HEIGHT);
    setWindowTitle(WINDOW_TITLE);
    setWindowIcon(QIcon(":/Pictures/24.jpg"));
    ansMsg.setWindowTitle("答案");
    double size = 400;
    ansMsg.resize(size, size * 0.618);
    // setWindowIcon(QIcon("D:\\Pictures\\24.jpg"));
}

// 初始化按钮
void MainWindow::buttonInit() {
    QPushButton* hi = this->sideBtn[0];
    hi->setText("提示");
    connect(hi, &QPushButton::clicked, [this](){
        QString t("提示：");
        t.append(ans[0].c_str());
        QPalette darkGreen;
        darkGreen.setColor(QPalette::WindowText,Qt::darkGreen);
        hint->setPalette(darkGreen);
        this->hint->setText(t);
        // this->sbar->addPermanentWidget(hint);
    });
    QPushButton *show = this->sideBtn[1];
    show->setText("显示答案");
    connect(show, &QPushButton::clicked, [this](){
        QString s;
        for (auto &i: ans) {
            s.append(i.c_str());
            s.append("<br>");
        }
        this->ansMsg.setText(s);
        this->ansMsg.show();
    });
    QPushButton *ne = this->sideBtn[2];
    ne->setText("下一题");
    connect(ne, &QPushButton::clicked, [this](){
        this->displayNewQuestion();
        this->textEditInit();
        this->ansLabel->clear();
        this->hint->clear();
    });
    QPushButton *ex = this->sideBtn[3];
    ex->setText("退出游戏");
    connect(ex, &QPushButton::clicked, this, &QWidget::close);


    QPushButton *ok = this->inputBtn;
    ok->setText("提交");
    connect(ok, &QPushButton::clicked, [this](){
        auto input = this->getCustomInput();
        if (judgeInput(input)) {
            QPalette red;
            red.setColor(QPalette::WindowText,Qt::darkGreen);
            ansLabel->setPalette(red);
            ansLabel->setText("答案正确！");
        } else {
            QPalette red;
            red.setColor(QPalette::WindowText,Qt::red);
            ansLabel->setPalette(red);
            ansLabel->setText("很遗憾，答案错误。");
        }
    });
}

void MainWindow::menuInit() {
    bar = ui->menubar;
    bar->setParent(this);
    // bar = new QMenuBar(this);
    // setMenuBar(bar);
    auto helpMenu = new HelpMenu();
    // helpMenu->setAttribute(Qt::WA_DeleteOnClose);
    bar->addMenu(helpMenu);
    // bar->show();
}

void MainWindow::statusBarInit() {
    this->sbar = statusBar();
    setStatusBar(sbar);
    QLabel *label = new QLabel("已解决问题：0个", this);
    sbar->addWidget(label);
}

// UI布局元素转换成成员变量
void MainWindow::uiInit() {
    ui->setupUi(this);
    this->textEdit = ui->plainTextEdit;
    this->inputBtn = ui->inputBtn;
    this->sideBtn = {ui->s1, ui->s2, ui->s3, ui->s4};
    this->lcdNums = {ui->lcd1, ui->lcd2, ui->lcd3, ui->lcd4};
    this->ansLabel = ui->anslabel;
    QFont font;
    font.setPointSize(14);
    this->ansLabel->setFont(font);
    this->hint = ui->hintLabel;
    this->hint->setFont(font);
}

// 初始化题目
void MainWindow::lcdInit() {
    nums = {EASY_NUMBERS};
    QPalette color;
    color.setColor(QPalette::WindowText, Qt::darkBlue);
    this->lcdNums[0]->setPalette(color);
    color.setColor(QPalette::WindowText, Qt::darkCyan);
    this->lcdNums[1]->setPalette(color);
    color.setColor(QPalette::WindowText, Qt::darkGreen);
    this->lcdNums[2]->setPalette(color);
    color.setColor(QPalette::WindowText, Qt::magenta);
    this->lcdNums[3]->setPalette(color);
    srand(time(0));
    // srand(1);
    displayNewQuestion();
}

void MainWindow::displayNewQuestion() {
    // 没有题目可出时直接返回
    if (idxVi.size() == nums.size()) {
        return;
    }
    int len = nums.size();
    int idx = rand() % len;
    while (idxVi[idx] == true) {
        idx = rand() % len;
    }
    this->idxVi[idx] = true;
    this->chooseIdx = idx;
    auto &choose = this->nums[idx];
    this->seLcd(choose);
}

void MainWindow::textEditInit() {
    auto obj = this->textEdit;
    obj->clear();
    obj->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
}

std::string MainWindow::getCustomInput() {
    auto s = this->textEdit->document();
    auto str = s->toPlainText().toStdString();
    return str;
    // int idx = str.find(':');
    // return str.substr(idx + 1);
}

static double calculate(string s) {
    Calculate t;
    return t.Solve(s);
}

bool MainWindow::judgeInput(string s) {
    string str;
    for (auto i: s) {
        if (i != ' ' && i != '\n') {
            str += i;
        }
    }
    s = str;
    for (auto &c: s) {
        if (!isdigit(c) && c != '(' && c != ')' && c != '+' && c != '-' && c != '*' && c != '/') {
            return false;
        }
    }
    vector<int>arr;
    int tmp = 0;
    for (auto i: s) {
        if (isdigit(i)) {
            tmp = tmp * 10 + (i - '0');
        } else {
            if (tmp) {
                arr.push_back(tmp);
                tmp = 0;
            }
        }
    }
    if (tmp) {
        arr.push_back(tmp);
    }
    sort(arr.begin(), arr.end());
    if (arr.size() < 4) {
        return false;
    }
    auto &obj = nums[chooseIdx];
    for (int i = 0; i < 4; i++) {
        if (arr[i] != obj[i]) {
            return false;
        }
    }
    return fabs(calculate(s) - 24) < 1e-8;
}

void MainWindow::seLcd(vector<int> &arr) {
    Solve24Game so;
    this->ans = so.getAns(arr);
    for (int i = 0; i < lcdNums.size(); i++) {
        lcdNums[i]->display(arr[i]);
    }
}
